package xx.services;

import java.io.PrintWriter;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;

import xx.db.QueryRunner;
import xx.db.sql.Select;
import xx.entity.page.PageLayout;
import xx.services.util.Names;

public class PageCache
{
    private Map<Integer, Page> map = new HashMap<Integer, Page>();

    private static PageCache c = new PageCache();

    private PageCache()
    {
    }

    public static final PageCache getInstance()
    {
        return c;
    }

    public boolean contains(int pageHash)
    {
        boolean b = map.containsKey(pageHash);
        if (b)
        {
            map.get(pageHash).resetTask();
        }
        return b;
    }

    public Page get(int pageHash)
    {
        return map.get(pageHash);
    }

    /**
     * 加入缓存，默认保存1小时
     * 
     * @param pageHash
     * @param value
     * @author 陈祥 2011-9-13
     */
    public synchronized void push(final Page page, long cacheTime)
    {
        map.put(page.getHash(), page);

        if (cacheTime <= 0)
            cacheTime = 10;

        Timer timer = new Timer();
        timer.schedule(new TimerTask()
        {
            @Override
            public void run()
            {
                if (page.isRead)
                {
                    page.load(null);
                }
                else
                {
                    map.remove(page.getHash());
                }
            }
        }, cacheTime * 1000);
    }

    public void remove(int hash)
    {
        map.remove(hash);
    }

    public static void init()
    {
        Map<Integer, Page> newMap = new HashMap<Integer, Page>();
        Select select = new Select(new QueryRunner(Names.FRAMEWORK, null), null);
        List<xx.entity.page.Page> list;
        try
        {
            select.from(xx.entity.page.Page.class);
            list = select.go();
        }
        catch (SQLException e)
        {
            e.printStackTrace();
            return;
        }

        for (xx.entity.page.Page page : list)
        {
            int hash = page.isIndex() ? "index".hashCode() : page.getPagekey().hashCode();
            Page p = c.instancePage(hash, page.getTitle(), null);
            p.setPage(page).load(null);
            newMap.put(hash, p);
        }
        synchronized (c.map)
        {
            c.map = newMap;
        }
    }

    public Page instancePage(int hash, String title, String content)
    {
        return new Page(hash, title, content);
    }

    class Page
    {
        private Page(int hash, String title, String content)
        {
            this.hash = hash;
            this.title = title;
            this.content = content;
        }

        private int hash;

        private String title;

        private String content = null;

        private xx.entity.page.Page page;

        private boolean isRead = true;

        public String getContent()
        {
            return content;
        }

        public Page setContent(String content)
        {
            this.content = content;
            return this;
        }

        public int getHash()
        {
            return hash;
        }

        public Page setHash(int hash)
        {
            this.hash = hash;
            return this;
        }

        public String getTitle()
        {
            return title;
        }

        public Page setTitle(String title)
        {
            this.title = title;
            return this;
        }

        public xx.entity.page.Page getPage()
        {
            return page;
        }

        public Page setPage(xx.entity.page.Page page)
        {
            this.page = page;
            return this;
        }

        public boolean isRead()
        {
            return isRead;
        }

        public void load(PrintWriter out)
        {
            StringBuilder sb = new StringBuilder();
            String[] templet = page.getTemplet().split("\\$\\{container}");
            String header = templet[0].replaceAll("\\$\\{title}", page.getTitle()).replaceAll(
                    "\\$\\{keywords}", page.getKeywords()).replaceAll("\\$\\{description}",
                    page.getDescription());
            if (out != null)
            {
                out.print(header);
                out.print("\n");
            }
            sb.append(header);
            try
            {
                List<PageLayout> layouts = page.getLayouts();
                for (PageLayout layout : layouts)
                {
                    String html = layout.toHtml();
                    if (out != null)
                    {
                        out.print(html);
                        out.print("\n");
                        out.flush();
                    }
                    sb.append(html);
                }
            }
            catch (SQLException e)
            {
                if (out != null)
                {
                    out.print("系统繁忙！");
                    out.print("\n");
                    out.flush();
                }
                e.printStackTrace();
            }

            String footer = templet[1];
            if (out != null)
            {
                out.print(footer);
                out.flush();
            }
            sb.append(footer);

            content = sb.toString();

            resetTask();
        }

        private void resetTask()
        {
            if (task != null)
                task.cancel();
            task = new TimerTask()
            {
                @Override
                public void run()
                {
                    isRead = false;
                }
            };

            timer.schedule(task, 24 * 60 * 60 * 1000);
        }

        private Timer timer = new Timer();

        private TimerTask task = null;
    }
}
